

#include <stdint.h>
#include <stdbool.h>


uint8_t i7816_xor_sequence(uint8_t buf[], uint32_t len)
{
    uint32_t i;
    uint8_t xor;

    for(xor = i = 0; i < len; i++)
    {
        xor ^= buf[i];
    }

    return xor;
}

uint16_t i7816_convert_fi_code_to_value(uint8_t fi_code)
{	
	static const unsigned int fi_table[16] = {
		372,372,558,744,
		1116,1488,1860,0,
		/*0,*/128,//SAM AV3非标准Fi
		512,768,1024,
		1536,2048,0,0
		};
	return fi_table[fi_code];	
}

uint8_t i7816_convert_di_code_to_value(uint8_t di_code)
{
	static const unsigned int di_table[16] = {
			0,1,2,4,
			8,16,32,64,
			12,20,0,0,
			0,0,0,0
		};
	return di_table[di_code];
}

uint8_t i7816_nibble_setbit_number(uint8_t data)
{
    const static uint8_t set_bit_num[] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
    return set_bit_num[data & 0x0F];
}

uint8_t i7816_reverse_byte(uint8_t ch)
{
    uint8_t reverse;

    reverse = (ch >> 4) | (ch << 4);
    reverse = ((reverse & 0x33) << 2) | ((reverse & 0xCC) >> 2);
    reverse = ((reverse & 0x55) << 1) | ((reverse & 0xAA) >> 1);

    return reverse;
}

uint16_t i7816_to_inverse(uint16_t data)
{    
    uint16_t parity_bit;

    data = ~data;
    parity_bit = data & 0x0100;

    return (uint16_t)i7816_reverse_byte((uint8_t)data) | parity_bit;
}


uint32_t i7816_etu2clk(uint32_t etu, uint8_t FiDi)
{
	uint32_t F, D;
	uint32_t clock;
	
	F = i7816_convert_fi_code_to_value(FiDi >> 4);
	D = i7816_convert_di_code_to_value(FiDi & 0x0F);

	if( F == 0 || D == 0)
	{
		return 0;
	}
	//clock = etu * F * etu_timer_fraction / D;
	clock = etu*F/D; 
	return clock;
}


